import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ZkConnMySQL {

    private static final String CONFIG_PREFIX = "/myconfig";
    private static final String CONFIG_USER = CONFIG_PREFIX + "/user";
    private static final String CONFIG_PWD = CONFIG_PREFIX + "/password";
    private static final String CONFIG_DRIVER = CONFIG_PREFIX + "/driver";
    private static final String CONFIG_URL = CONFIG_PREFIX + "/url";
    private static MyDataSource myDataSource = null;
    private static Connection conn = null;

    static class MyIZkDataListener implements IZkDataListener {

        public MyIZkDataListener() {
        }

        @Override
        public void handleDataChange(String path, Object data) throws Exception {
            //定义接受通知之后的处理逻辑
            String name = path.split("/")[2];
            conn.close();
            Thread.sleep(1000);
            //更改了目标数据库
            System.out.println("数据库配置参数发生改变，改变的参数为：" + name + "，释放旧连接成功，正在重新连接数据库");

            //创建新的连接池
            myDataSource = new MyDataSource(name, String.valueOf(data));
            //重新获得数据库连接
            conn = myDataSource.getConn();

            //新的数据库中也准备了测试表，表中内容与上一个测试表不同
            System.out.println("数据库连接成功");
            System.out.println("--------查询测试表数据---------");
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("select * from test");
            while(rs.next()){
                System.out.println("id:" + rs.getString(1) + " name:" + rs.getString(2));
            }
            System.out.println("--------查询测试表数据---------");
            rs.close();
            stmt.close();
        }

        @Override
        public void handleDataDeleted(String path) throws Exception {
            //数据删除 -> 节点删除
            System.out.println(path + " is deleted!!");
        }
    }

    public static void main(String[] args) throws InterruptedException, SQLException {
        //获取zkclient对象
        ZkClient zkClient = new ZkClient("linux121:2181");

        //设置自定义的序列化类型
        zkClient.setZkSerializer(new ZkStrSerializer());

        //从zookeeper拉取MySQL配置参数
        Object user = zkClient.readData(CONFIG_USER);
        Object pwd = zkClient.readData(CONFIG_PWD);
        Object driver = zkClient.readData(CONFIG_DRIVER);
        Object url = zkClient.readData(CONFIG_URL);

        //初始化数据库连接池
        myDataSource = new MyDataSource(String.valueOf(user), String.valueOf(pwd)
                , String.valueOf(driver), String.valueOf(url));
        //获得数据库连接
        conn = myDataSource.getConn();
        System.out.println("数据库连接成功");
        System.out.println("--------查询测试表数据---------");
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("select * from test");
        while(rs.next()){
            System.out.println("id:" + rs.getString(1) + " name:" + rs.getString(2));
        }
        System.out.println("--------查询测试表数据---------");
        rs.close();
        stmt.close();

        //注册监听器，监听器监听节点数据是否改变，定义接收到通知后的处理逻辑
        zkClient.subscribeDataChanges(CONFIG_USER, new MyIZkDataListener());
        zkClient.subscribeDataChanges(CONFIG_PWD, new MyIZkDataListener());
        zkClient.subscribeDataChanges(CONFIG_DRIVER, new MyIZkDataListener());
        zkClient.subscribeDataChanges(CONFIG_URL, new MyIZkDataListener());

        Thread.sleep(Integer.MAX_VALUE);
    }
}
